<script setup lang="ts">
import { ref, watch, computed } from 'vue'

interface FieldConfig {
  key: string
  label: string
  type: 'text' | 'number' | 'email' | 'select' | 'textarea' | 'password' | 'date'
  required?: boolean
  readonly?: boolean
  options?: { title: string, value: any }[]
  rules?: any[]
  placeholder?: string
  rows?: number
  defaultValue?: any
}

interface Props {
  visible: boolean
  title?: string
  fields: FieldConfig[]
  loading?: boolean
  width?: string | number
  showReset?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  title: '新增数据',
  loading: false,
  width: 600,
  showReset: true
})

const emit = defineEmits<{
  'update:visible': [value: boolean]
  'save': [data: Record<string, any>]
  'cancel': []
  'reset': []
}>()

const formData = ref<Record<string, any>>({})
const formRef = ref()

// 计算属性：对话框显示状态
const dialogVisible = computed({
  get: () => props.visible,
  set: (value) => emit('update:visible', value)
})

// 初始化表单数据
const initFormData = () => {
  const emptyData: Record<string, any> = {}
  props.fields.forEach(field => {
    if (field.defaultValue !== undefined) {
      emptyData[field.key] = field.defaultValue
    } else {
      switch (field.type) {
        case 'number':
          emptyData[field.key] = 0
          break
        case 'select':
          emptyData[field.key] = null
          break
        default:
          emptyData[field.key] = ''
      }
    }
  })
  formData.value = emptyData
}

// 监听弹窗打开，初始化表单
watch(() => props.visible, (visible) => {
  if (visible) {
    initFormData()
  }
}, { immediate: true })

// 验证规则
const getFieldRules = (field: FieldConfig) => {
  const rules = [...(field.rules || [])]
  if (field.required) {
    rules.unshift((v: any) => {
      if (v === null || v === undefined || v === '') {
        return `${field.label}不能为空`
      }
      return true
    })
  }
  if (field.type === 'email') {
    rules.push((v: string) => !v || /.+@.+\..+/.test(v) || '请输入有效的邮箱地址')
  }
  return rules
}

// 保存数据
const handleSave = async () => {
  const { valid } = await formRef.value?.validate()
  if (valid) {
    emit('save', { ...formData.value })
  }
}

// 重置表单
const handleReset = () => {
  formRef.value?.reset()
  initFormData()
  emit('reset')
}

// 取消新增
const handleCancel = () => {
  formRef.value?.reset()
  emit('cancel')
  dialogVisible.value = false
}

// 获取输入框类型
const getInputType = (fieldType: string) => {
  switch (fieldType) {
    case 'email': return 'email'
    case 'number': return 'number'
    case 'password': return 'password'
    case 'date': return 'date'
    default: return 'text'
  }
}
</script>

<template>
  <VDialog 
    v-model="dialogVisible" 
    :width="width"
    persistent
    class="add-dialog"
  >
    <VCard class="dialog-card">
      <!-- 标题栏 -->
      <VCardTitle class="dialog-title">
        <VIcon class="title-icon" color="primary">mdi-plus-circle</VIcon>
        {{ title }}
        <VSpacer />
        <VBtn 
          icon="mdi-close" 
          variant="text" 
          size="small"
          @click="handleCancel"
        />
      </VCardTitle>

      <VDivider />

      <!-- 表单内容 -->
      <VCardText class="dialog-content">
        <VForm ref="formRef" class="add-form">
          <VRow>
            <VCol 
              v-for="field in fields" 
              :key="field.key"
              cols="12"
              :sm="field.type === 'textarea' ? 12 : 6"
            >
              <!-- 文本输入框 -->
              <VTextField
                v-if="field.type === 'text' || field.type === 'email' || field.type === 'password'"
                v-model="formData[field.key]"
                :label="field.label"
                :type="getInputType(field.type)"
                :placeholder="field.placeholder"
                :readonly="field.readonly"
                :rules="getFieldRules(field)"
                variant="outlined"
                density="comfortable"
                clearable
                class="form-field"
              />

              <!-- 数字输入框 -->
              <VTextField
                v-else-if="field.type === 'number'"
                v-model.number="formData[field.key]"
                :label="field.label"
                type="number"
                :placeholder="field.placeholder"
                :readonly="field.readonly"
                :rules="getFieldRules(field)"
                variant="outlined"
                density="comfortable"
                clearable
                class="form-field"
              />

              <!-- 日期输入框 -->
              <VTextField
                v-else-if="field.type === 'date'"
                v-model="formData[field.key]"
                :label="field.label"
                type="date"
                :readonly="field.readonly"
                :rules="getFieldRules(field)"
                variant="outlined"
                density="comfortable"
                class="form-field"
              />

              <!-- 选择框 -->
              <VSelect
                v-else-if="field.type === 'select'"
                v-model="formData[field.key]"
                :label="field.label"
                :items="field.options"
                :placeholder="field.placeholder"
                :readonly="field.readonly"
                :rules="getFieldRules(field)"
                variant="outlined"
                density="comfortable"
                clearable
                class="form-field"
              />

              <!-- 多行文本框 -->
              <VTextarea
                v-else-if="field.type === 'textarea'"
                v-model="formData[field.key]"
                :label="field.label"
                :placeholder="field.placeholder"
                :readonly="field.readonly"
                :rules="getFieldRules(field)"
                :rows="field.rows || 3"
                variant="outlined"
                density="comfortable"
                clearable
                class="form-field"
              />
            </VCol>
          </VRow>
        </VForm>
      </VCardText>

      <VDivider />

      <!-- 操作按钮 -->
      <VCardActions class="dialog-actions">
        <VBtn
          v-if="showReset"
          variant="outlined"
          color="warning"
          @click="handleReset"
          :disabled="loading"
          prepend-icon="mdi-refresh"
        >
          重置
        </VBtn>
        <VSpacer />
        <VBtn
          variant="outlined"
          color="grey"
          @click="handleCancel"
          :disabled="loading"
        >
          取消
        </VBtn>
        <VBtn
          color="primary"
          @click="handleSave"
          :loading="loading"
          prepend-icon="mdi-content-save"
        >
          保存
        </VBtn>
      </VCardActions>
    </VCard>
  </VDialog>
</template>

<style scoped>
.add-dialog :deep(.v-overlay__content) {
  margin: 24px;
}

.dialog-card {
  border-radius: 16px;
  overflow: hidden;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}

.dialog-title {
  background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%);
  color: #1565c0;
  font-weight: 700;
  font-size: 1.25rem;
  padding: 20px 24px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.title-icon {
  font-size: 1.5rem;
  animation: bounce 2s infinite;
}

@keyframes bounce {
  0%, 20%, 50%, 80%, 100% {
    transform: translateY(0);
  }
  40% {
    transform: translateY(-5px);
  }
  60% {
    transform: translateY(-3px);
  }
}

.dialog-content {
  flex: 1;
  overflow-y: auto;
  padding: 24px;
  background: linear-gradient(180deg, #fafafa 0%, #ffffff 100%);
}

.add-form {
  width: 100%;
}

.form-field :deep(.v-field) {
  border-radius: 12px;
  transition: all 0.3s ease;
  background: rgba(255, 255, 255, 0.9);
}

.form-field :deep(.v-field:hover) {
  background: rgba(255, 255, 255, 1);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transform: translateY(-1px);
}

.form-field :deep(.v-field--focused) {
  box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.2);
  transform: translateY(-1px);
}

.form-field :deep(.v-field--variant-outlined.v-field--focused .v-field__outline) {
  border-width: 2px;
}

.form-field :deep(.v-label) {
  font-weight: 500;
}

.dialog-actions {
  background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
  padding: 16px 24px;
  gap: 12px;
  border-top: 1px solid #e9ecef;
}

.dialog-actions .v-btn {
  border-radius: 10px;
  font-weight: 600;
  text-transform: none;
  min-width: 80px;
  transition: all 0.3s ease;
}

.dialog-actions .v-btn:hover {
  transform: translateY(-2px);
}

.dialog-actions .v-btn[color="primary"] {
  box-shadow: 0 4px 12px rgba(25, 118, 210, 0.25);
}

.dialog-actions .v-btn[color="primary"]:hover {
  box-shadow: 0 6px 16px rgba(25, 118, 210, 0.35);
}

@media (max-width: 600px) {
  .add-dialog :deep(.v-overlay__content) {
    margin: 12px;
  }
  
  .dialog-title {
    padding: 16px 20px;
    font-size: 1.125rem;
  }
  
  .dialog-content {
    padding: 20px;
  }
  
  .dialog-actions {
    padding: 12px 20px;
    flex-direction: column;
    gap: 8px;
  }
  
  .dialog-actions .v-btn {
    width: 100%;
  }
}
</style>
